using System;
using System.Collections.Generic;
using System.Net;
using System.Text;

using NUnit.Framework;
using OpenSocial.Net;

namespace OpenSocial.Net.Tests
{
	[TestFixture]
	public class OpenSocialTests
	{
		const string DOMAIN = "http://www.ecademy.com"; //"http://sandbox.orkut.com";
		const string AUTH_VALUE = "authValue";
		const ulong ianUserID = 1; //15474536637173028522;

		#region AuthenticationTests

		private const string NEXT_URL = "";
		private const string SCOPE = "";

		[Test]
		public void GetAuthSubProxyUriTest()
		{
			bool secure = false;
			bool session = false;

			string expectedUrl = string.Format(@"https://www.google.com/accounts/AuthSubRequest?scope={0}&session={1}&secure={2}&next={3}", SCOPE, session ? 1 : 0, secure ? 1 : 0, NEXT_URL);
			Uri url = Authentication.GetAuthSubProxyUri(NEXT_URL, SCOPE, secure, session);
			Assert.IsNotNull(url.ToString(), "url was null");
			Assert.IsNotEmpty(url.ToString(), "url was empty");
			Assert.AreEqual(expectedUrl, url.ToString(), "auth sub url was not as expected");
		}
		
		#endregion AuthenticationTests

		#region ProviderBaseTests

		[Test]
		public void ConstructorTest()
		{

			ProviderBase provider = new ProviderBase(DOMAIN);
			Assert.AreEqual(provider.Domain, DOMAIN, "domain was not set in constructor 1");
			Assert.AreEqual(provider.AuthToken, "", "auth contained value but expected to be empty in constructor 1");

			ProviderBase provider2 = new ProviderBase(DOMAIN, AUTH_VALUE);
			Assert.AreEqual(provider2.Domain, DOMAIN, "domain was not set in constructor 2");
			Assert.AreEqual(provider2.AuthToken, AUTH_VALUE, "auth value was not set properly in constructor 2");
		}

		[Test]
		public void AuthTokenTest()
		{
			//check initial auth value
			string origAuthValue = "initialValue";
			ProviderBase provider = new ProviderBase(DOMAIN, origAuthValue);
			string authValue1 = provider.AuthToken;

			//change and check secondary auth value
			string intendedAuthValue2 = "secondValue";
			provider.AuthToken = intendedAuthValue2;
			string authValue2 = provider.AuthToken;

			Assert.AreEqual(origAuthValue, authValue1, "constructor did not set auth value correctly");
			Assert.AreEqual(intendedAuthValue2, authValue2, "property set did not set auth value correctly");
		}

		[Test]
		public void GetDataTest()
		{
			string url = "http://www.google.com";
			HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
			ProviderBase provider = new ProviderBase(DOMAIN, "");
			string responseData = provider.GetData(req);

			Assert.IsNotEmpty(responseData, "No data was returned.");
			Assert.IsTrue(responseData.Contains("Google"), "String 'Google' expected but not found.");
			Console.WriteLine(responseData);
		}

		[Test]
		public void GetOpenSocialDataTest()
		{
			ProviderBase provider = new ProviderBase(DOMAIN, "");
			string responseData = provider.GetOpenSocialData("http://www.google.com");
			Assert.IsNotEmpty(responseData, "No data was returned.");
			Assert.IsTrue(responseData.Contains("Google"), "String 'Google' expected but not found.");
			Console.WriteLine(responseData);

			provider = new ProviderBase(DOMAIN, "authToken");
			responseData = provider.GetOpenSocialData("http://www.google.com");
			Assert.IsNotEmpty(responseData, "No data was returned.");
			Assert.IsTrue(responseData.Contains("Google"), "String 'Google' expected but not found.");
			Console.WriteLine(responseData);
		}

		#endregion ProviderBaseTests

		#region PeopleTests

		#region PeopleProviderTests
		
		[Test]
		public void GetPersonTest()
		{
			ulong userID = ianUserID;
			People.PeopleProvider provider = new People.PeopleProvider(DOMAIN, "");
			Console.WriteLine(string.Format("provider domain: {0}", provider.Domain));
			People.Person person = provider.GetPerson(userID);

			//summary is not a required property
			Assert.IsNotNull(person, "person is null");
			Assert.IsFalse(string.IsNullOrEmpty(person.ID), "ID is null or empty");
			Assert.IsFalse(string.IsNullOrEmpty(person.Title), "Title is null or empty");
			Assert.IsTrue(person.Updated > DateTime.MinValue, "Date is not set");
		}
		
		#endregion PeopleProviderTests

		#region PeopleBuilderTests

		/// <summary>
		/// Parses the person from atom test.
		/// </summary>
		[Test]
		public void BuildPersonTest()
		{
			string atom = 
				@"<entry xmlns='http://www.w3.org/2005/Atom' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005'>" +
				"<id>http://sandbox.orkut.com:80/feeds/people/14358878523263729569</id>" +
				"<updated>2007-10-28T14:01:29.948-07:00</updated>" +
				"<title>Elizabeth Bennet</title>" +
				"<link rel='thumbnail' type='image/*' href='http://img1.orkut.com/images/small/1193601584/115566312.jpg'/>" +
				"<link rel='alternate' type='text/html' href='http://orkut.com/Profile.aspx?uid=17583631990196664929'/>" +
				"<link rel='self' type='application/atom+xml' href='http://sandbox.orkut.com:80/feeds/people/14358878523263729569'/>" +
				"<georss:where>" +
				"<gml:Point xmlns:gml='http://www.opengis.net/gml'>" +
				"<gml:pos>51.668674 -0.066235</gml:pos>" +
				"</gml:Point>" +
				"</georss:where>" +
				"<gd:extendedProperty name='lang' value='en-US'/>" +
				"<gd:postalAddress/>" +
				"</entry>";
			People.PeopleBuilder builder = new OpenSocial.Net.People.PeopleBuilder();
			People.Person person = builder.BuildPerson(atom);

			//summary is not a required property
			Assert.IsNotNull(person, "person is null");
			Assert.IsFalse(string.IsNullOrEmpty(person.ID), "ID is null or empty");
			Assert.IsFalse(string.IsNullOrEmpty(person.Title), "Title is null or empty");
			Assert.IsTrue(person.Updated > DateTime.MinValue, "Date is not set");
		}

		#endregion PeopleBuilderTests

		#endregion PeopleTests
	}
}
